package com.ruoyi.sms.common;

import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.enums.RspEnmu;
import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.common.utils.spring.SpringUtils;
import lombok.extern.slf4j.Slf4j;

import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLConnection;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.Set;

/**
 * @desc 短信工具类
 * @author pgc
 * @date 2021-10-27 11:35
 */
@Slf4j
public class SmsUtil {

    //短信定时任务流转间隔时间
    public static final String SMS_INTERVAL_TIME = "sys_dict:sms_interval_time";
    /**
     * 发送post请求
     * @param url  路径
     * @param jsonObject  参数(json类型)
     * @param headParam 请求头参数
     * @return
     * @throws ParseException
     * @throws IOException
     */
    public String sendPost(String url, JSONObject jsonObject, Map<String,String> headParam) throws Exception {

        String body = "";
        //创建httpclient对象
        CloseableHttpClient client = HttpClients.createDefault();
        //创建post方式请求对象
        HttpPost httpPost = new HttpPost(url);
        //设置请求时间 20秒
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectionRequestTimeout(60*1000)//连接超时
                .setSocketTimeout(60*1000)//请求超时
                .setConnectTimeout(60*1000)//读取超时
                .build();
        //装填参数
        StringEntity s = new StringEntity(jsonObject.toString(), "utf-8");
        s.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE,
                "application/json"));
        //设置参数到请求对象中
        httpPost.setEntity(s);
        //设置header信息
        //指定报文头【Content-type】、【User-Agent】
//        httpPost.setHeader("Content-type", "application/x-www-form-urlencoded");
        httpPost.setHeader("Content-type", "application/json");
        //设置请求头
        if(null !=headParam && !headParam.isEmpty()){
            for(String key : headParam.keySet()){
                httpPost.setHeader(key, headParam.get(key));
            }
        }
        httpPost.setConfig(requestConfig);
        CloseableHttpResponse response = null;
        HttpEntity entity = null;
        try {
            //执行请求操作，并拿到结果（同步阻塞）
            response = client.execute(httpPost);
            //获取结果实体
            entity = response.getEntity();
            if (entity != null) {
                //按指定编码转换结果实体为String类型
                body = EntityUtils.toString(entity, "utf-8");
            }
        } catch (ConnectTimeoutException ex) {
            log.error("-----请求连接超时:",ex);
            throw new BusinessException(ex.getMessage(), RspEnmu.CONNET_TIMED_OUT);
        } catch (Exception ex) {
            log.error("-----请求异常，异常信息：", ex);
            throw new BusinessException(ex.getMessage(), RspEnmu.NETWORK_EXCEPTION);
        }finally {
            if (entity != null) {
                EntityUtils.consume(entity);
            }
            //释放链接
            if(response!=null){
                response.close();
            }
        }

        return body;
    }

    //get方式：参数放置在url上
    public String httpConn(String requestUrl, String param)throws Exception{

        String urlNameString = requestUrl + "?" + param;
        String result="";
        try{
            URL url = new URL(urlNameString);
            //打开url的连接
            URLConnection conn = url.openConnection();
            //设置连接属性
            conn.setConnectTimeout(5*1000);
            //获得输入流，并封装为字符
            BufferedReader in = new BufferedReader(
                    new InputStreamReader(conn.getInputStream()));//获得网络返回的输入流
            String line = "";

            while ((line = in.readLine()) != null) {
                result += line;
            }
            result=new String(result.getBytes(),"UTF-8");
            log.info("----------- send BetaSMS  result : "+result);
        }catch(Exception e){
            log.error("--------- : ",e);
            throw new BusinessException(e.getMessage(), RspEnmu.NETWORK_EXCEPTION);
        }
        return result;
    }

    /**
     * 判断当前时间是否有定时任务执行, 定时任务时间点半小时后都算在这区间
     * @param set 定时任务时间点 集合
     */
    public boolean isExecuteTimeHorizon(Set<Integer> set){
        int intervalTime = SpringUtils.getBean(RedisCache.class).getCacheObject(SMS_INTERVAL_TIME);
        long time = System.currentTimeMillis();
        SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
        String currentTime = dateFormat.format(time);
        for(int timePoint : set){
            if(timePoint == Integer.parseInt(currentTime.split(":")[0])){
                int timeNumber = Integer.valueOf(currentTime.split(":")[1])*60+Integer.valueOf(currentTime.split(":")[2]);
                if(timeNumber < intervalTime)
                {
                    return true;
                }
            }
        }
        return false;
    }


    /**
     * buka 运营商 MD5 32 签名生成
     */
    /**
     * MD5加密字符串
     *
     * @param str
     * @return
     * @throws NoSuchAlgorithmException
     * @throws UnsupportedEncodingException
     */
    public static String encoderByMd5(String str){
        MessageDigest md5 = null;
        try {
            md5 = MessageDigest.getInstance("MD5");
            md5.update((str).getBytes("UTF-8"));
        } catch (NoSuchAlgorithmException e) {
            log.error("----buka  create MD5 sign :",e);
        }catch (UnsupportedEncodingException e) {
            log.error("----buka  create MD5 sign :",e);
        }
        byte b[] = md5.digest();
        int i;
        StringBuffer buf = new StringBuffer("");
        for (int offset = 0; offset < b.length; offset++) {
            i = b[offset];
            if (i < 0) {
                i += 256;
            }
            if (i < 16) {
                buf.append("0");
            }
            buf.append(Integer.toHexString(i));
        }
        return buf.toString();
    }

    /**
     * 获取精确到秒的时间戳
     * @param date
     * @return
     */
    public static int getSecondTimestampTwo(Date date){
        if (null == date) {
            return 0;
        }
        String timestamp = String.valueOf(date.getTime()/1000);
        return Integer.valueOf(timestamp);
    }


}
